// axios配置  可自行根据项目进行更改，只需更改该文件即可，其他文件可以不动
import { VAxios } from './Axios'
import type { AxiosTransform } from './axiosTransform'
import type { AxiosResponse } from 'axios'
import axios from 'axios'
import { checkStatus } from './checkStatus'
import { joinTimestamp, formatRequestDate } from './helper'
import { RequestEnum, ResultEnum, ContentTypeEnum } from '@/utils/enums/httpEnum'

import { isObject, isString } from '@/utils/is/'
import { setObjToUrlParams } from '@/utils/urlUtils'

import type { RequestOptions, Result } from './types'

import { Modal, message as Message, notification } from 'antd'
import { storage } from '@/utils/Storage'
// import {uuid} from '@/utils'
import { v4 as uuidv4 } from 'uuid'

const urlPrefix = import.meta.env.REACT_APP_API_PREFIX // 接口前缀
const baseUrl = import.meta.env.VITE_APP_URL // 接口地址

/**
 * @description: 数据处理，方便区分多种处理方式
 */
const transform: AxiosTransform = {
  /**
   * @description: 处理请求数据
   */
  transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
    // const { $message: Message, $dialog: Modal } = window; chatAdmin
    const {
      isShowMessage = true,
      isShowErrorMessage,
      isShowSuccessMessage,
      successMessageText,
      errorMessageText,
      isTransformResponse,
      isReturnNativeResponse
    } = options
    // 是否返回原生响应头 比如：需要获取响应头时使用该属性
    if (isReturnNativeResponse) {
      return res.data
    }
    // 不进行任何处理，直接返回
    // 用于页面代码可能需要直接获取code，data，message这些信息时开启
    if (!isTransformResponse) {
      return res.data
    }
    const { errCode, errMsg } = res.data || res
    // 接口请求成功，直接返回结果
    if (errCode === 0) {
      return res.data
    }
    console.log(res)
    if(res.data.errCode === 1001 && res.data.errDlt.includes('token 输入有误')) {
        Message.error('token缺失，请重新登陆')
        window.location.href = '/login'
    }
    if(res.data.errCode === 1501 || res.data.errCode === 1502 || res.data.errCode === 1503 || res.data.errCode === 1504 || res.data.errCode === 1505 || res.data.errCode === 1506 || res.data.errCode === 1507 || res.data.errCode === 20101){
        Message.error('登陆状态过期')
        window.location.href = '/login'
    }
    console.log(res)
    Message.error(errMsg || '系统内部错误')
    return Promise.reject(errMsg || '系统内部错误')
  },

  // 请求之前处理config
  beforeRequestHook: (config, options) => {
    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options

    if (joinPrefix) {
      config.url = `${urlPrefix}${config.url}`
    }

    if (apiUrl && isString(apiUrl)) {
      config.url = `${apiUrl}${config.url}`
    }
    const params = config.params || {}
    const data = config.data || false
    if (config.method?.toUpperCase() === RequestEnum.GET) {
      if (!isString(params)) {
        // 给 get 请求加上时间戳参数，避免从缓存中拿数据。
        // config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
      } else {
        // 兼容restful风格
        config.url = config.url + params + `${joinTimestamp(joinTime, true)}`
        config.params = undefined
      }
    } else {
      if (!isString(params)) {
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        formatDate && formatRequestDate(params)
        config.data = data
        config.params = params
        if (joinParamsToUrl) {
          config.url = setObjToUrlParams(
            config.url as string,
            Object.assign({}, config.params, config.data)
          )
        }
      } else {
        // 兼容restful风格
        config.url = config.url + params
        config.params = undefined
      }
    }
    return config
  },

  /**
   * @description: 请求拦截器处理
   */
  requestInterceptors: config => {
    // 请求之前处理config
    const token = storage.get('token')
    if (token) {
      config.headers = {
        token,
        ...config.headers
      }
    }
    return config
  },

  /**
   * @description: 响应错误处理
   */
  responseInterceptorsCatch: (error: any) => {
    const { response, code, message } = error || {}
    // TODO 此处要根据后端接口返回格式修改
    const msg: string =
      response && response.data && response.data.message ? response.data.message : ''
    const err: string = error.toString()
    try {
      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
        Message.error('接口请求超时,请刷新页面重试!')
        return
      }
      if (err && err.includes('Network Error')) {
        Modal.info({
          title: '网络异常',
          content: '请检查您的网络连接是否正常!',
          okText: '确定',
          onOk: () => {
            console.log('ok')
          }
        })
        return
      }
    } catch (e) {
      throw new Error(e as string)
    }
    if (response && response.status === 401) {
      storage.clear()
      /** 未登陆逻辑后续再补充 */
      notification.error({
        message: message,
        description: 'token过期或未登录或没有权限'
      })
      window.location.href = '/login'
    }
    // 请求是否被取消
    const isCancel = axios.isCancel(error)
    if (!isCancel) {
      checkStatus(error.response && error.response.status, msg, Message)
    } else {
      console.warn(error, '请求被取消！')
    }
    return error
  }
}

const operationID = uuidv4()
const Axios = new VAxios({
  baseURL: baseUrl,
  timeout: 100 * 1000,
  // 接口前缀
  prefixUrl: urlPrefix,
  headers: {
    'Content-Type': ContentTypeEnum.JSON,
    operationID: operationID
  },
  // 数据处理方式
  transform,
  // 配置项，下面的选项都可以在独立的接口请求中覆盖
  requestOptions: {
    // 默认将prefix 添加到url
    joinPrefix: false,
    // 是否返回原生响应头 比如：需要获取响应头时使用该属性
    isReturnNativeResponse: false,
    // 需要对返回数据进行处理
    isTransformResponse: true,
    // post请求的时候添加参数到url
    joinParamsToUrl: false,
    // 格式化提交参数时间
    formatDate: true,
    // 消息提示类型
    errorMessageMode: 'none',
    // 接口地址
    apiUrl: import.meta.env.REACT_APP_BASE_URL
  },
  withCredentials: false
})

export default Axios
